package site.jlopen.service.quartzTrigger;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson2.JSON;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import site.jlopen.assets.spring.KusciaApiInfoCache;
import site.jlopen.domain.node.event.KusciaNodeEvent;
import site.jlopen.entity.BaseResponse;
import site.jlopen.entity.KusciaApiInfo;
import site.jlopen.entity.quartz.KusciaJobDataMap;
import site.jlopen.kuscia.model.job.JobStatusResponeVo;
import site.jlopen.kuscia.model.task.TaskStatuPartie;
import site.jlopen.kuscia.model.task.TaskStatusResponeVo;
import site.jlopen.kuscia.service.job.AbstractJobManager;
import site.jlopen.mapper.job.KusciaJobMapper;
import site.jlopen.mapper.job.KusciaJobTaskMapper;
import site.jlopen.mapper.node.KusciaNodeMapper;
import site.jlopen.secret.model.job.SecretJobLogResp;
import site.jlopen.service.imp.JobTaskConvertForApiService;
import site.jlopen.service.intf.quartz.QuartzService;

@Component
@Slf4j
public class KusciaJobTrigger implements Job {
	private static Logger logger = LoggerFactory.getLogger(KusciaJobTrigger.class);

	private final KusciaNodeMapper nodeMapper;

	private final AbstractJobManager nodeManager;
    
	private final KusciaJobMapper jobMapper;

	private final KusciaJobTaskMapper taskMapper;

	private final QuartzService quartzService;
	
	private final RestTemplate restTemplate;
	
	private final JobTaskConvertForApiService jobTaskService;

	public KusciaJobTrigger(KusciaNodeMapper nodeMapper, AbstractJobManager nodeManager, KusciaJobTaskMapper taskMapper,
			KusciaJobMapper jobMapper, QuartzService quartzService, RestTemplate restTemplate, JobTaskConvertForApiService jobTaskService) {
		super();
		this.nodeMapper = nodeMapper;
		this.nodeManager = nodeManager;
		this.jobMapper = jobMapper;
		this.taskMapper = taskMapper;
		this.quartzService = quartzService;
		this.restTemplate = restTemplate;
		this.jobTaskService = jobTaskService;
	}

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		log.info("=========================业务逻辑====================");
		log.info("jobName:{}", context.getJobDetail().getKey().getName());
		log.info("jobGroup:{}", context.getJobDetail().getKey().getGroup());
		log.info("triggerName:{}", context.getTrigger().getKey().getName());
		log.info("triggerGroup:{}", context.getTrigger().getKey().getGroup());
		log.info("上次触发时间:{}", DateUtil.formatDateTime(context.getPreviousFireTime()));
		log.info("本次触发时间:{}", DateUtil.formatDateTime(context.getFireTime()));
		log.info("下次触发时间:{}", DateUtil.formatDateTime(context.getNextFireTime()));
		log.info("调度时间:{}", DateUtil.formatDateTime(context.getScheduledFireTime()));
		try {
			JobDataMap dataMap = context.getMergedJobDataMap();
			String DATA = dataMap.getString("DATA");
			if (StringUtils.isNotBlank(DATA)) {
				KusciaJobDataMap dataInfo = JSON.parseObject(DATA, KusciaJobDataMap.class);
				KusciaApiInfo apiInfo = KusciaApiInfoCache.getInstance().getCache(dataInfo.getNodeId());
				if (null == apiInfo) {
					KusciaNodeEvent node = nodeMapper.selectByKey(dataInfo.getNodeId());
					apiInfo = new KusciaApiInfo(node.getNodeProtocol(), node.getNodeGrpc()).ext(node.getNodeToken(),
							node.getNodeCert(), node.getNodeKey(), node.getNodeCa());
				}
				JobStatusResponeVo jobInfo = nodeManager.queryJob(apiInfo, String.valueOf(dataInfo.getJobId()));
				List<TaskStatusResponeVo> tasks = jobInfo.getTasks();
				for (TaskStatusResponeVo vo : tasks) {
					if (!"PENDING".equals(vo.getState())) {
						String errText = null;
						List<TaskStatuPartie> taskStatuParties = vo.getTaskStatuParties();
						if (null != taskStatuParties && taskStatuParties.size() > 0 && !"RUNNING".equals(vo.getState())) {
							errText = vo.getErrMsg();
							for (TaskStatuPartie partie : taskStatuParties) {
								if ("FAILED".equals(partie.getState())) {
									errText = errText + "\\\\n" + partie.getDomainId() + "\\\\n" + partie.getErrMsg();
								}
							}
						}
						try {
							taskMapper.updateTaskStateById(vo.getTaskId(), vo.getState(), errText);
						} catch (Exception e) {
							logger.error("修改{}任务状态异常，终止了监听：{}", DATA, e);
				            sendPostRequest(dataInfo.getCallback(), dataInfo.getProjectId(), dataInfo.getProjectName());
							quartzService.deleteCronJob(context.getJobDetail().getKey().getName(),
									context.getJobDetail().getKey().getGroup(), context.getTrigger().getKey().getName(),
									context.getTrigger().getKey().getGroup());
						}
					}else {
						JobStatusResponeVo onejobInfo = new JobStatusResponeVo();
						List<TaskStatusResponeVo> onetasks = new ArrayList<TaskStatusResponeVo>();
						onetasks.add(vo);
						onejobInfo.setJobId(jobInfo.getJobId());
						onejobInfo.setInitiator(jobInfo.getInitiator());
						onejobInfo.setState(jobInfo.getState());
						onejobInfo.setTasks(onetasks);
						sendPostRequest(dataInfo.getCallback(), dataInfo.getProjectId(), dataInfo.getProjectName());
					}
				}
				if(jobInfo.getState().equals("FAILED") || jobInfo.getState().equals("SUCCEEDED")) {
		               jobMapper.updateJobState(Long.valueOf(dataInfo.getJobId()), jobInfo.getState());
		               sendPostRequest(dataInfo.getCallback(), dataInfo.getProjectId(), dataInfo.getProjectName());
		               quartzService.deleteCronJob(context.getJobDetail().getKey().getName(),
								context.getJobDetail().getKey().getGroup(), context.getTrigger().getKey().getName(),
								context.getTrigger().getKey().getGroup());
		               return;
		        }
			}
		} catch (Exception e) {
			logger.error("任务执行异常，终止了监听：{}", e);
			quartzService.deleteCronJob(context.getJobDetail().getKey().getName(),
					context.getJobDetail().getKey().getGroup(), context.getTrigger().getKey().getName(),
					context.getTrigger().getKey().getGroup());
		}
	}
	
	@Async
	private void sendPostRequest(String url, Long projectId, String projectTitle) {
        logger.info("回调完成开始回调：{}:{}", url, projectId);
		if(StringUtils.isBlank(url)) {
			return ;
		}
		BaseResponse<SecretJobLogResp> logs = jobTaskService.logs(projectId);
		if(logs.getStatus() != 0) {
			return;
		}
		SecretJobLogResp resp = logs.getData();
		resp.setProjectTitle(projectTitle);
        try {
        	// 创建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            // 将请求头和请求体封装成HttpEntity
            HttpEntity<SecretJobLogResp> entity = new HttpEntity<SecretJobLogResp>(resp, headers);
            // 使用RestTemplate发起POST请求
            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
            // 返回响应体
            logger.info("回调结果", response.getBody());
		} catch (Exception e) {
            logger.info("回调完成回调异常：{}", e);
		}
    }
}
